
var urlmapping = require('../models/url.js'),
    testcaseBizType = require('../models/testcaseBizType.js').bizKeyTypes,
    _ = require('lodash'),
    urlmappingModel = urlmapping.urls;
var mongoose = require('mongoose');
var moment = require('moment');
var xmlConverter = require("xml2js");
var commonMethods = require('../utils/commonMethods');

var insertUrl = function(data,success,error){
    var urlSave = new urlmappingModel({
        url:data.url,
        bizKey:data.bizKey,
        soapMethod:data.soapMethod,
        type:data.type,
        params:data.params,
        responseData:data.responseData,
        tag:data.tag,
        create_date:moment(new Date()).format('DD MMM YYYY HH:mm'),
        last_update_date:''
    });
    urlSave.save(function(err){
        if(err){
            error({status:'400',reason:err});
        } else {
            success({status:'200',data:'insert url success'})
        }
    });
};

var removeUrl = function (data,success,error) {
    urlmappingModel.remove({url:data},function (err,result) {
        if(err){
            error({status:'400',reason:err});
        } else {
            success({status:'200',data:'remove url success'})
        }
    })
};
var checkUrlUnique = function (data,success,error) {
    urlmappingModel.findOne({url:data.url},function(err,result){
        if(err){
            error({status:"400",reason:err})
        } else {
            if(result != null){
                success({status:'200',data:result});
            } else {
                success({status:'404',data:"can not find this url"});
            }
        }
    })
};

var updateUrl = function (data,success,error) {
    urlmappingModel.update({_id:data._id},data,function(err,docs){
        if(err){
            error({status:'400',reason:err});
        } else {
            console.log('docs ',JSON.stringify(docs))
            success({status:'200',data:docs})
        }
    })
};

var filterByKeyWords = function(keywordRegexs, data, success, error) {
    urlmappingModel.find({
        $or:
            [{"bizKey.bizKeyValue": {$in: keywordRegexs}}, {tag: {$in: keywordRegexs}}]
    }, function (err, result) {
        if (err) {
            error({status: '400', reason: err});
        } else {
            commonMethods.getFilterPageList(data, result, success);
        }
    })
//    $regex: %"target"/"target"%
};

var findAllUrlPageList = function(data,success,error){
    urlmappingModel.find(function(err,result){
        if(err){
            error({status:"400",reason:err});
        } else {
            commonMethods.getFilterPageList(data,result,success);
        }
    })
}

function getKeyWordRegexs(keywords) {
    var keywordList = keywords.split(',');
    var regexs = [];
    for (let i = 0; i < keywordList.length; i++) {
        regexs.push(new RegExp(keywordList[i], 'i'));
    }
    return regexs;
}

var getUrlPageList = function(data,success,error){
    if(data.keywords){
        var regexs = getKeyWordRegexs(data.keywords);
        filterByKeyWords(regexs,data,success,error);
    }else{
        findAllUrlPageList(data,success,error);
    }
};

var getUrlList = function (data,success,error) {
    urlmappingModel.find(function (err,result) {
        if(err){
            error({status:"400",reason:err});
        } else {
            success(result)
        }
    })
};

var batchRemoveUrl = function(req,res,next) {
    var urlIdArr = req.params.urlIds.split(',');
    urlmappingModel.remove({_id:{$in:urlIdArr}},function(err){
        if(err){
            next({status:'400',reason:err})
        } else {
            res.send({status:'200'});
        }
    })
}

function getByURl(req, res, next){
    var expectedurl = req.body.url;
    if(_.isEmpty(expectedurl)){
        res.send({status:"400",message:'POST data url is empty'});
    }else{
        urlmappingModel.findOne({
            url : expectedurl
        },function(err, data){
            if(err){
                next(err)
            }else{
                if(_.isEmpty(data)){
                    res.send({status:"400",message:'no this data'});
                }else {
                    res.send({status:"200",data:data});
                }
            }
        });
    }
}

function getByParamsMethod(req, res, next){
    var expUrl = req.body.url;
    var expParams = req.body.params;
    var expMethod = req.body.method;
    console.log(expUrl)
    console.log(expParams)
    console.log(expMethod)
    if(_.isEmpty(expParams) || _.isEmpty(expParams)){
        res.send({status:'400',message:'Post data is empty'});
    }else{
        urlmappingModel.findOne({
            url: expUrl,
            soapMethod: expMethod,
            params: expParams
        },function(err, data){
            if(err){
                next(err)
            }else{
                if(_.isEmpty(data)){
                    res.send({status:"400",message:'no this data'});
                }else {
                    res.send({status:"200",data:data});
                }
            }
        });
    }
}


function parseSoapRequestbody(req, res, next){
    var originalrequestXML = req.body.originalrequestXML;

    if(_.isEmpty(originalrequestXML)){
        res.json({status: '500', message: 'post params is Empty'});
    }else{
        convertRequestXML(originalrequestXML, (err, result) => {
            if(err){
                res.json({status:'500', message: 'Wrong XML Format'});
            }else{
                res.json({status:'200', data: result});
            }
        });
    }
}

function convertRequestXML(reqXML, callback){
    xmlConverter.parseString(reqXML,  {explicitArray : false}, function(err, json) {  
        if(err){
            callback(err);
        }else{
            console.log(JSON.stringify(json));
            var resJson = modifyNodeName(json);
            console.log(JSON.stringify(resJson));
            callback(null, resJson);
        }
    });
}


function modifyNodeName(jsonObj){
    
        for(var key in jsonObj){
            var newKey = key.split(':')[1];
            var nodeType = typeof(jsonObj[key]);
            if(_.isEqual(nodeType, 'string')){
                jsonObj[newKey] = jsonObj[key];
            }else{
                jsonObj[newKey] = modifyNodeName(jsonObj[key], newKey);
            }
            delete jsonObj[key];
        }
        return jsonObj;
    }

function removeFirstSlash(url) {
    if(url.indexOf('/') === 0){
        return url.replace(new RegExp('/'),'')
    }
    return url;
}
    
function getAllRepleacedUrlList(req, res, next) {
    urlmappingModel.find(function (err, data) {
        if (err) {
            console.log(err)
            next(err)
        } else {
            var urlList = [];
            try {
                data.forEach(function (item) {
                    var urlItem = {};
                    urlItem.id = item.id;
                    urlItem.url = commonMethods.replaceSourceDataWithKeyValue(item.url, item.bizKey);
                    urlItem.url = removeFirstSlash(urlItem.url);
                    urlList.push(urlItem);
                });
                console.log(urlList);
                res.send({ status: "200", data: urlList });
            } catch (error) {
                console.log(error)
                res.send({status:"500", errorMsg: error});
            }
        }
    });
}

function getById(req, res, next) {
    urlmappingModel.findById(req.params.id, function (err, data) {
        if (err) {
            next(err);
        } else {
            if (_.isEmpty(data)) {
                res.send({ status: "400", message: 'no this data' });
            } else {
                data.responseData = commonMethods.replaceSourceDataWithKeyValue(data.responseData, data.bizKey);
                res.send({ status: "200", data:data });
            }
        }
    });
}
module.exports = {
    getByURl : getByURl,
    getByParamsMethod : getByParamsMethod,
    insertUrl : insertUrl,
    removeUrl : removeUrl,
    getUrlList : getUrlList,
    checkUrlUnique:checkUrlUnique,
    updateUrl: updateUrl,
    parseSoapRequestbody:parseSoapRequestbody,
    getUrlPageList:getUrlPageList,
    batchRemoveUrl:batchRemoveUrl,
    getAllRepleacedUrlList : getAllRepleacedUrlList,
    getById: getById
}